<?php
/**
 * Copyright (c) 2006, PORTALIER Julien
 * 
 * Licensed under The LGPL License
 * Redistributions of files must retain the above copyright notice.
 * 
 * To use you'll need to:
 * 
 *    1. download SwiftMailer 3.0.0 from http://swiftmailer.org
 *    2. unpack it in somewhere
 *    3. rename the lib/ folder to swift/
 *    4. move it to the vendors/ directory
 *    5. if you have vendors/swift/Swift.php, vendors/swift/Swift/... etc., you're set.
 * 
 * Hotmail.com's stupidity:
 * 
 * Every email sent is in utf-8 (standardized around the web),
 * but hotmail.com just can't deal with it. There are 2 possible
 * hacks.
 * 
 * 1. translate the body to an ISO charset, thus destroying
 *    messages mixing multiple languages or with unexistant
 *    characters in output charset :/
 * 
 * 2. encode the entities and send the email as latin1. It's
 *    kinda ugly, but it works.
 * 
 * @package      FeatherCMS
 * @subpackage   Swift
 * @copyright    Copyright (c) 2006, Julien PORTALIER
 * @link         http://julien.portalier.com
 * @license      http://www.opensource.org/licenses/lgpl-license.php The LGPL License
 */

class SwiftComponent
{
	protected $controller;
	
	protected $recipients;
	protected $from;
	public $mailer;
	
	public $error;
	
	
	function startup(Controller &$controller)
	{
		$this->controller = &$controller;
	}
	
	// swiftmailer
	
	function connect()
	{
		// loads required libs
		$this->controller->load->vendors('swift'.DS.'Swift');
		$this->controller->load->vendors('swift'.DS.'Swift'.DS.'Connection'.DS.Config::swift_protocol);
		
		// creates transport method
		switch(Config::swift_protocol)
		{
			case 'SMTP':
				$conn = new Swift_Connection_SMTP(Config::swift_options);
				
				// SMTP auth?
				if (Config::smtp_username)
				{
					$conn->setUsername(Config::smtp_username);
					$conn->setPassword(Config::smtp_password);
				}
				break;
			
			case 'Sendmail':
				$conn = new Swift_Connection_Sendmail(Config::swift_options);
				break;
			
			case 'NativeMail':
				$conn = new Swift_Connection_NativeMail(Config::swift_options);
				break;
			
			default:
				trigger_error('You must set a known protocol (SMTP, Sendmail, NativeMail) for use with swift.', E_USER_ERROR);
		}
		
		// creates mailer
		$this->mailer = new Swift($conn);
		
		// creates a recipient list
		$this->recipients = new Swift_RecipientList();
	}
	
	function send($subject='', $from=null, $body=null)
	{
		if (!isset($this->mailer))
			$this->connect();
		
		// from who?
		if (isset($from))
		{
			if (is_array($from))
			{
				// email + name
				list($email, $name) = $from;
				$this->setFrom($email, $name);
			}
			else
			{
				// email
				$this->from = $from;
			}
		}
		
		// creates a new message
		$message = new Swift_Message($subject);
		
		if (is_null($body))
			$body = $this->renderBody();
		
		// h4ck to deal with hotmail.com
		if ($this->hasHotmailRecipient())
		{
			$message->setCharset(Config::email_charset);
			
			// this is just ugly :/
			$body = htmlentities(html_entity_decode($body), ENT_NOQUOTES, Config::charset);
			$body = str_replace(array('&lt;', '&gt;'), array('<', '>'), $body);
			$body = preg_replace('/&amp;#(\d+);/', '&#\1;', $body);
		}
		else {
			$message->setCharset(Config::charset);
		}
		
		$message->attach(new Swift_Message_Part($body, 'text/html'));
		
		// @todo Add a text part (html rendered as text)
#		$this->controller->load->libs('html_parse');
#		$message->attach(new Swift_Message_Part(HtmlParse::renderAsText::($body));
		
		// send
		$nb_recipients = count($this->recipients->getTo()) + count($this->recipients->getCc()) + count($this->recipients->getBcc());
		$nb_sent = $this->mailer->send($message, $this->recipients, $this->from);
		
		// errors?
		if (!$nb_sent)
			$this->error = _("An error occured and your email wasn't sent.");
		elseif ($nb_sent != $nb_recipients)
			$this->error = _("An error occured and your email wasn't sent to all recipients.");
	}
	
	function setFrom($email, $name=null)
	{
		$this->from = new Swift_Address($email, $name);
	}
	
	function addRecipient($email, $name=null, $method="To")
	{
		if (!isset($this->recipients))
			$this->connect();
		
		$method = "add$method";
		$this->recipients->$method($email, $name);
	}
	
	// internals
	
	protected function hasHotmailRecipient()
	{
		$recipients = array_keys(array_merge(
			$this->recipients->getTo(),
			$this->recipients->getCc(),
			$this->recipients->getBcc()
		));
		
		foreach($recipients as $email)
		{
			if (stripos($email, 'hotmail.com'))
				return true;
		}
		
		return false;
	}
	
	protected function renderBody()
	{
		$autoRender      = $this->controller->autoRender;
		$alreadyRendered = $this->controller->alreadyRendered;
		
		ob_start();
		$this->controller->render('emails'.DS.$this->controller->action, 'email');
		$body = ob_get_clean();
		
		$this->controller->autoRender      = $autoRender;
		$this->controller->alreadyRendered = $alreadyRendered;
		
		return $body;
	}
	/*
	protected function __error()
	{
		Error::show(500, 'swift', array('swift' => $this->mailer));
	}
	*/
}
?>